/**
 *****************************************************************************
 * DESC ：. 
 * Author : Junwei Zhang 
 * CREATEDATE ：2012-6-30 
 * MODIFYLIST ：       	Name 			 Date 			Reason/Contents
 * 				------------------------------------------------------ 
 * 				 	Junwei Zhang     2012-6-30		Created.
 ****************************************************************************
 **/
package com.me.server;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
 * 服务器端消息解析类. <br/>
 * 下午8:03:25 2012-6-30
 * 
 * @Author <a href="mailto:mestudying@sina.com">Junwei Zhang</a><br/>
 **/
public class MessageParser extends DefaultHandler {
	/** A new member. */
	private boolean isNewMember = false;
	/** Member list. */
	private List<OneMember> listMembers = new ArrayList<OneMember>();
	private List<OneMessage> listMessage = new ArrayList<OneMessage>();
	private List<GlobalUser> listGlobalUsers = new ArrayList<GlobalUser>();

	/**  */
	private String currentTag = null;
	private String lastCommand = null;
	private String lastCommandID = null;
	private String lastError = null;

	/**
	 * MESSAGE tag includes some messages. This tag provides the following properties:
	 * NAME,CONTENT,SENDER,STATUS,TO,TYPE.
	 */
	public static final String MESSAGE = "MESSAGE";
	public static final String MESSAGE_TYPE = "type";
	private static final String MESSAGE_CONTENT = "content";
	private static final String MESSAGE_SENDER = "sender";
	private static final String MESSAGE_STATUS = "status";
	private static final String MESSAGE_TO = "to";
	private static final String MESSAGE_SUBJECT = "subject";
	private static final String MESSAGE_ID = "id";

	/** New member for registered users. */
	public static final String NEW_MEMBER = "NEW_MEMBER";
	/** GLOBAL_USER tag for registered users */
	public static final String GLOBAL_USER = "GLOBAL_USER";

	/** Member. */
	public static final String MEMBER = "MEMBER";
	public static final String MEMBER_NAME = "name";
	public static final String MEMBER_PASSWD = "passwd";
	public static final String MEMBER_STATUS = "status";
	public static final String MEMBER_IP = "ip";
	public static final String MEMBER_TYPE = "type";
	public static final String MEMBER_SID = "sid";

	/**
	 * 解析从客户端接收到消息.
	 * 
	 * @param xmlMessage
	 */
	public boolean parsing(String xmlMessage) {
		// TODO Auto-generated method stub
		this.listMembers.clear(); // 清除上次解析的用户.
		this.listMessage.clear(); // 清除上次解析的消息.
		this.isNewMember = false;
		this.lastCommand = null;
		this.lastCommandID = null;
		boolean parsedSuccessfully = false;
		SAXParserFactory parserFactory = SAXParserFactory.newInstance();
		parserFactory.setValidating(true);
		try {
			SAXParser parser = parserFactory.newSAXParser();
			InputStream in = new ByteArrayInputStream(xmlMessage.getBytes("UTF-8"));
			parser.parse(in, this);
			parsedSuccessfully = true;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return parsedSuccessfully;
	}

	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		// TODO Auto-generated method stub
		this.currentTag = qName;
		if (this.currentTag.equalsIgnoreCase(NEW_MEMBER)) {
			/** Register new account. */
			String username = attributes.getValue(MEMBER_NAME);
			String password = attributes.getValue(MEMBER_PASSWD);
			OneMember member = new OneMember(username, null, password, null, null, null);
			this.listMembers.add(member);
			this.isNewMember = true;
		} else if (this.currentTag.equalsIgnoreCase(MEMBER)) {
			String username = attributes.getValue(MEMBER_NAME);
			String password = attributes.getValue(MEMBER_PASSWD);
			String status = attributes.getValue(MEMBER_STATUS);
			String ip = attributes.getValue(MEMBER_IP);
			String type = attributes.getValue(MEMBER_TYPE);
			String sid = attributes.getValue(MEMBER_SID);
			OneMember member = new OneMember(username, status, password, ip, type, sid);
			this.listMembers.add(member);
		} else if (this.currentTag.equalsIgnoreCase(MESSAGE)) {
			String tempType = attributes.getValue(MESSAGE_TYPE);
			if (tempType.equalsIgnoreCase("command") && attributes.getValue(MESSAGE_TO) == null) {
				this.lastCommand = attributes.getValue(MESSAGE_CONTENT);
				this.lastCommandID = attributes.getValue(MESSAGE_ID);
			} else {
				String content = attributes.getValue(MESSAGE_CONTENT);
				String sender = attributes.getValue(MESSAGE_SENDER);
				String status = attributes.getValue(MESSAGE_STATUS);
				String to = attributes.getValue(MESSAGE_TO);
				String subject = attributes.getValue(MESSAGE_SUBJECT);
				String id = attributes.getValue(MESSAGE_ID);
				OneMessage oneMessage = new OneMessage(content, sender, status, to, tempType, subject, id);
				this.listMessage.add(oneMessage);
			}
		} else if (this.currentTag.equalsIgnoreCase(GLOBAL_USER)) {
			String userName = attributes.getValue("name");
			String password = attributes.getValue("passwd");
			String role = attributes.getValue("role");
			GlobalUser user = new GlobalUser(userName, password, role, false);
			this.listGlobalUsers.add(user);
		}
	}

	/** Whether a new account register? */
	public boolean isNewMember() {
		return isNewMember;
	}

	public OneMember getAMember(int index) {
		return this.listMembers.get(index);
	}

	/**
	 * 注册新用户.
	 * 
	 * @param userName
	 * @param password
	 * @return
	 */
	public GlobalUser createGlobalUserObject(String userName, String password, String role, boolean makeHash) {
		return new GlobalUser(userName, password, role, makeHash);
	}

	/** 用户类. */
	public class OneMember {
		/** Member's name */
		public String name = null;
		/** Member's password */
		public String passwd = null;
		/** Member's status-normal busy robot */
		public String status = null;
		/** IP */
		public String ip = null;
		/** web-client persistent chat-room */
		public String type = null;
		/** Session ID */
		public String sid = null;

		public OneMember(String name, String status, String password, String ip, String type, String sid) {
			this.name = name;
			this.passwd = password;
			this.status = status != null ? status : "normal";
			this.ip = ip;
			this.type = type != null ? type : JTalkerMember.USER_TYPE_PERSISTENT;
			this.sid = sid;
		}
	}

	/** 注册用户类. */
	public class GlobalUser {
		public static final String USER = "user";
		public static final String ADMIN = "admin";
		public static final String ROOT = "root";
		public static final String CONTACTS_ALL = "*";

		/** GlobalUser's name */
		public String name = null;
		/** GlobalUser's password */
		public String passwd = null;
		private String role = GlobalUser.USER;

		public GlobalUser(String userName, String password, String role, boolean makeHash) {
			this.name = userName;
			if (makeHash) {
				this.passwd = JTalkServer.makeHash(password);
			} else {
				this.passwd = password;
			}
			this.setRole(role);
		}

		private void setRole(String role) {
			if (role != null) {
				this.role = role;
			}
		}

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}

		public String getPasswd() {
			return passwd;
		}

		public void setPasswd(String passwd) {
			this.passwd = passwd;
		}

		public String getRole() {
			return this.role;
		}

	}

	/**
	 * 消息类.
	 * 
	 * @author Administrator
	 * 
	 */
	public class OneMessage {

		public String content = null;
		public String sender = null;
		public String senderStatus = null;
		public String messageReceivers = null;
		public String messageType = null;
		public String messageSubject = null;
		public String messageID = null;

		public OneMessage(String content, String sender, String senderStatus, String messageReceivers,
				String messageType, String messageSubject, String messageID) {
			// TODO Auto-generated constructor stub
			this.content = content;
			this.sender = sender;
			this.senderStatus = senderStatus;
			this.messageReceivers = messageReceivers;
			this.messageType = messageType;
			this.messageSubject = messageSubject;
			this.messageID = messageID;
		}
	}

	/**
	 * 获取消息接收者.
	 * 
	 * @return
	 */
	public String getReceivers() {
		// TODO Auto-generated method stub
		String messageReceivers = null;
		if (this.listMessage.size() > 0) {
			messageReceivers = this.getAMessage(0).messageReceivers;
		}
		return messageReceivers;
	}

	/**
	 * 获取一条消息.
	 * 
	 * @param index
	 * @return
	 */
	private OneMessage getAMessage(int index) {
		OneMessage m = null;
		if (this.listMessage.size() > 0) {
			m = this.listMessage.get(0);
		}
		return m;
	}

	/**
	 * 获取消息接收者数组.
	 * 
	 * @return
	 */
	public String[] getReceiversAsArray() {
		return this.getAMessage(0).messageReceivers.split(";;");
	}

	/**
	 * 获取一条消息内容.
	 * 
	 * @return
	 */
	public String getMessage() {
		String content = null;
		if (this.getAMessage(0) != null) {
			content = this.getAMessage(0).content;
		}
		return content;
	}

	/**
	 * 获取一条消息的类型.
	 * 
	 * @return
	 */
	public String getMessageType() {
		String type = null;
		if (this.getAMessage(0) != null) {
			type = this.getAMessage(0).messageType;
		}
		return type;
	}

	/**
	 * 获取一条消息的主题.
	 * 
	 * @return
	 */
	public String getMessageSubject() {
		String subject = null;
		if (this.getAMessage(0) != null) {
			subject = this.getAMessage(0).messageSubject;
		}
		return subject;
	}

	/**
	 * 获取一条消息的ID.
	 * 
	 * @return
	 */
	public String getMessageID() {
		String id = null;
		if (this.getAMessage(0) != null) {
			id = this.getAMessage(0).messageID;
		}
		return id;
	}

	/**
	 * 获取命令.
	 * 
	 * @return
	 */
	public String getCommand() {
		return this.lastCommand;
	}

	/**
	 * 获取命令ID
	 * 
	 * @return
	 */
	public String getCommandID() {
		return this.lastCommandID;
	}

	/**
	 * 获取用户状态."Busy" "normal"
	 * 
	 * @return
	 */
	public String getMemberStatus() {
		if (this.listMembers.size() == 1) {
			return this.listMembers.get(0).status;
		} else {
			return null;
		}
	}

	public GlobalUser createGlobalUserObject(String userName, String password, String role) {
		return new GlobalUser(userName, password, role, true);
	}

	/**
	 * 解析XML文件.
	 * @param globalUserFile
	 * @return
	 */
	public boolean parsing(File globalUserFile) {
		this.lastError = null;
		this.isNewMember = false;
		if (!globalUserFile.canRead()) {
			this.lastError = "Can't load file";
			return false;
		}
		try {
			SAXParserFactory factory = SAXParserFactory.newInstance();
			factory.setValidating(false);
			SAXParser parser = factory.newSAXParser();
			parser.parse(globalUserFile, this);
		} catch (Exception e) {
			return false;
		}
		return true;
	}

	/**
	 * 获取注册用户的个数.
	 * 
	 * @return
	 */
	public int getGlobalUserNum() {
		return this.listGlobalUsers.size();
	}

	/**
	 * 获取某个注册用户.
	 * 
	 * @param index
	 * @return
	 */
	public GlobalUser getAGlobalUser(int index) {
		if (index < this.getGlobalUserNum()) {
			return this.listGlobalUsers.get(index);
		} else {
			return null;
		}
	}

}
